/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package com.inspur.edp.lcm.metadata.core;

import com.inspur.edp.lcm.metadata.api.entity.GspProject;
import com.inspur.edp.lcm.metadata.api.entity.MetadataPackageHeader;
import com.inspur.edp.lcm.metadata.api.entity.MetadataProject;
import com.inspur.edp.lcm.metadata.api.entity.Module;
import com.inspur.edp.lcm.metadata.api.entity.OperationEnum;
import com.inspur.edp.lcm.metadata.api.entity.ProcessMode;
import com.inspur.edp.lcm.metadata.api.entity.bo.BOInfo;
import com.inspur.edp.lcm.metadata.api.entity.uri.MetadataURI;
import com.inspur.edp.lcm.metadata.api.mvnEntity.MavenPackageRefs;
import com.inspur.edp.lcm.metadata.api.service.MetadataProjectService;
import com.inspur.edp.lcm.metadata.common.FileServiceImp;
import com.inspur.edp.lcm.metadata.common.Utils;
import com.inspur.edp.lcm.metadata.devcommon.ManagerUtils;
import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.springframework.util.StringUtils;


/**
 * 元数据工程服务
 *
 * @author zhaoleitr
 */
public class MetadataProjectServiceImp implements MetadataProjectService {

    private final MetadataProjectCoreService projectCoreService = new MetadataProjectCoreService();

    @Override
    public boolean isExistProjFile(String path) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        return projectCoreService.isExistProjFile(absolutePath);
    }

    @Override
    public void rename(String path, String oldName, String newName) {
        try {
            Utils.checkEmpty(oldName, "oldName");
            Utils.checkEmpty(newName, "newName");
            Utils.checkEmpty(path, "path");
            //全路径
            String absolutePath = ManagerUtils.getAbsolutePath(path);
            projectCoreService.rename(absolutePath, oldName, newName);
        } catch (Exception e) {
            throw new RuntimeException("元数据工程重命名失败", e);
        }
    }

    @Override
    public MetadataProject getMetadataProjInfo(String path) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        MetadataProject metadataProjInfo = projectCoreService.getMetadataProjInfo(absolutePath);
        return metadataProjInfo;
    }

    @Override
    public String getJavaCompProjectPath(String path) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        return projectCoreService.getJavaCompProjectPath(absolutePath);
    }

    @Override
    public String getJavaProjectPath(String path) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        return projectCoreService.getJavaProjectPath(absolutePath);
    }

    @Override
    public MetadataProject getMetadataProjRecursively(String path, List<String> projectPath) {
        return projectCoreService.getMetadataProjRecursively(path, projectPath);
    }

    @Override
    public void create(String path, String projectName, String projectNameSpace, String packageName, String processMode) {
        try {
            //全路径
            String absolutePath = ManagerUtils.getAbsolutePath(path);
            String projectNameLower = projectName.toLowerCase();
            handleDefaultPath(absolutePath, projectNameLower);
            String projectPath = Paths.get(absolutePath).resolve(projectNameLower).resolve(Utils.getMetadataProjPath()).resolve(projectName + Utils.getMetadataProjSuffix()).toString();
            projectCoreService.create(projectPath, projectName, projectNameSpace, packageName, processMode);
        } catch (Exception e) {
            throw new RuntimeException("元数据工程创建失败", e);
        }
    }

    private void handleDefaultPath(String projPath, String projName) {
        String projFullPath = Paths.get(projPath).resolve(projName).toString();
        FileServiceImp fileServiceImp = new FileServiceImp();
        if (!fileServiceImp.isDirectoryExist(projFullPath)) {
            fileServiceImp.createDirectory(projFullPath);
        }

        String metadataProjPath = Paths.get(projFullPath).resolve(Utils.getMetadataProjPath()).toString();
        if (!fileServiceImp.isDirectoryExist(metadataProjPath)) {
            fileServiceImp.createDirectory(metadataProjPath);
        }
    }

    @Override
    public void createGspProject(String path, GspProject projectData) {
        if (StringUtils.isEmpty(path)) {
            throw new RuntimeException("路径不能为空");
        }
        ;
        //全路径
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        projectCoreService.createGspProject(absolutePath, projectData);
    }

    @Override
    public void updateMavenRefs(String projPath, MetadataProject metadataProj, MavenPackageRefs packageRefs) {
        projectCoreService.updateMavenRefs(projPath, metadataProj, packageRefs);
    }

    @Override
    public void updateMavenRefVersion(String projPath, MetadataProject metadataProj, MavenPackageRefs mavenPackageRefs) {
        projectCoreService.updateMavenRefVersion(projPath, metadataProj, mavenPackageRefs);
    }

    @Override
    public void updateRefs(String projPath, MetadataProject metadataProj, MetadataPackageHeader packageHeader) {
        projectCoreService.updateRefs(projPath, metadataProj, packageHeader);
    }

    @Override
    public void updateRefs(String projPath, MetadataPackageHeader packageHeader) {
        MetadataProject metadataProjInfo = getMetadataProjInfo(projPath);
        updateRefs(projPath, metadataProjInfo, packageHeader);
    }

    @Override
    public String getProjPath(String path) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        String projPath = projectCoreService.getProjPath(absolutePath);
        return projPath;
    }

    @Override
    public String getAbsolutePath(String path) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        return absolutePath;
    }

    @Override
    public List<String> getBuildOrder(String path) {
        String projPath = getProjPath(path);
        return projectCoreService.getBuildOrder(projPath);
    }

    @Override
    public Map<String, Map<String, Long>> getSourceDataModifiedTime(String projPath) {
        String absolutePath = ManagerUtils.getAbsolutePath(projPath);
        return projectCoreService.getSourceDataModifiedTime(absolutePath);
    }

    @Override
    public void setSourceDataModifiedTime(String projPath, List<String> types) {
        String absolutePath = ManagerUtils.getAbsolutePath(projPath);
        projectCoreService.setSourceDataModifiedTime(absolutePath, types);
    }

    @Override
    public boolean metadataChangesDetected(String projPath) {
        String absolutePath = ManagerUtils.getAbsolutePath(projPath);
        return projectCoreService.metadataChangesDetected(absolutePath);
    }

    @Override
    public boolean codeChangesDetected(String projPath, String type) {
        String absolutePath = ManagerUtils.getAbsolutePath(projPath);
        return projectCoreService.codeChangesDetected(absolutePath, type);
    }

    @Override
    public String getMavenUpdateFlag(String projPath) {
        String absolutePath = ManagerUtils.getAbsolutePath(projPath);
        return projectCoreService.getMavenUpdateFlag(absolutePath);
    }

    @Override
    public ProcessMode getProcessMode(String path) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        return projectCoreService.getProcessMode(absolutePath);
    }

    @Override
    public List<String> getProjPathsInPath(String path) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        List<String> projPaths = new ArrayList<>();
        projectCoreService.getProjPathsInPath(absolutePath, projPaths);
        return projPaths;
    }

    @Override
    public void setMavenUpdateFlag(String projPath, Boolean flag) {
        String absolutePath = ManagerUtils.getAbsolutePath(projPath);
        projectCoreService.setMavenUpdateFlag(absolutePath, flag);
    }

    @Override
    public String getMdpkgNameExistInBo(String path, String mdpkgName) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        String projPathExist = projectCoreService.getMdpkgNameExistInBo(absolutePath, mdpkgName);
        return projPathExist != null ? new File(projPathExist).getName() : projPathExist;
    }

    @Override
    public boolean isExistProjFileRecursively(String path) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        return projectCoreService.isExistProjFileRecursively(absolutePath);
    }

    @Override
    public String getBoPath(String path) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        return ManagerUtils.getRelativePath(projectCoreService.getBoPath(absolutePath));
    }

    @Override
    public boolean isInterpretation(String path) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        return projectCoreService.isInterpretation(absolutePath);
    }

    @Override
    public List<BOInfo> getBOInfo(String[] boids) {
        return projectCoreService.getBOInfo(boids);
    }

    @Override
    public void changeProcessMode(String path, ProcessMode processMode) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        projectCoreService.changeProcessMode(absolutePath, processMode);
    }

    @Override
    public boolean isMetadataChanged(String path, OperationEnum operationEnum) {
        return isMetadataChanged(path, operationEnum, null);
    }

    @Override
    public boolean isMetadataChanged(String path, OperationEnum operationEnum, FileFilter fileFilter) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        return projectCoreService.isMetadataChanged(absolutePath, operationEnum, fileFilter);
    }

    @Override
    public void updateMetadataChanges(String path, OperationEnum operationEnum) {
        updateMetadataChanges(path, operationEnum, null);
    }

    @Override
    public void updateMetadataChanges(String path, OperationEnum operationEnum, FileFilter fileFilter) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        projectCoreService.updateMetadataChanges(absolutePath, operationEnum, fileFilter);
    }

    @Override
    public boolean isRefMetadataChanged(String path, OperationEnum operationEnum, MetadataURI metadataURI) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        return projectCoreService.isRefMetadataChanged(absolutePath, operationEnum, metadataURI);
    }

    @Override
    public void updateRefMetadataChanged(String path, OperationEnum operationEnum, MetadataURI metadataURI) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        projectCoreService.updateRefMetadataChanged(absolutePath, operationEnum, metadataURI);
    }

    @Override
    public boolean isFileChanged(String path, OperationEnum operationEnum) {
        return isFileChanged(path, operationEnum, null);
    }

    @Override
    public boolean isFileChanged(String path, OperationEnum operationEnum, FilenameFilter filenameFilter) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        return projectCoreService.isFileChanged(absolutePath, operationEnum, filenameFilter);
    }

    @Override
    public boolean isFileChanged(String path, String key, String value, OperationEnum operationEnum) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        return projectCoreService.isFileChanged(absolutePath, key, value, operationEnum);
    }

    @Override
    public void updateFileChanges(String path, OperationEnum operationEnum) {
        updateFileChanges(path, operationEnum, null);
    }

    @Override
    public void updateFileChanges(String path, OperationEnum operationEnum, FilenameFilter filenameFilter) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        projectCoreService.updateFileChanges(absolutePath, operationEnum, filenameFilter);
    }

    @Override
    public void updateFileChanges(String path, String key, String value, OperationEnum operationEnum) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        projectCoreService.updateFileChanges(absolutePath, key, value, operationEnum);
    }

    @Override
    public List<File> getChangeFiles(String path, OperationEnum operationEnum) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        return projectCoreService.getChangeFiles(absolutePath, operationEnum);
    }

    @Override
    public void deleteChangeRecord(String path, OperationEnum operationEnum) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        projectCoreService.deleteChangeRecord(absolutePath, operationEnum);
    }

    @Override
    public String getProjectBinPath(String path) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        return projectCoreService.getProjectBinPath(absolutePath);
    }

    @Override
    public String getMdpkgName(String path) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        return projectCoreService.getMdpkgName(absolutePath);
    }

    @Override
    public String getSrcPathByModule(String path, Module module) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        return projectCoreService.getSrcPathByModule(absolutePath, module);
    }

    @Override
    public String getTargetPathByModule(String path, Module module) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        return projectCoreService.getTargetPathByModule(absolutePath, module);
    }
}
